package com.ala4.oxcafe.common.utils;

import java.io.IOException;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.Map;

/**
 * @author PING
 * @version 1.0.0
 * @date 2025/8/12 11:33
 */
public class HttpUtil {
    private static final HttpClient DEFAULT_HTTP_CLIENT = HttpClient.newBuilder()
            .version(HttpClient.Version.HTTP_2)
            .connectTimeout(Duration.ofSeconds(10))
            .build();

    /**
     * 发送 GET 请求
     *
     * @param url     请求地址
     * @param headers 请求头（可选）
     * @return 响应内容
     */
    public static String get(String url, Map<String, String> headers) throws IOException, InterruptedException {
        HttpRequest.Builder builder = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .GET();

        addHeaders(builder, headers);

        return sendRequest(builder.build());
    }


    public static String get(String url) throws IOException, InterruptedException {
        return get(url, null);
    }

    /**
     * 发送 POST 表单请求
     *
     * @param url      请求地址
     * @param formData 表单数据
     * @param headers  请求头（可选）
     * @return 响应内容
     */
    public static String postForm(String url, Map<String, String> formData, Map<String, String> headers)
            throws IOException, InterruptedException {

        String encodedForm = encodeFormData(formData);

        HttpRequest.Builder builder = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .header("Content-Type", "application/x-www-form-urlencoded")
                .POST(HttpRequest.BodyPublishers.ofString(encodedForm));

        addHeaders(builder, headers);

        return sendRequest(builder.build());
    }

    public static String postForm(String url, Map<String, String> formData)
            throws IOException, InterruptedException {

        return postForm(url, formData, null);
    }

    /**
     * 发送 POST JSON 请求
     *
     * @param url     请求地址
     * @param json    JSON 字符串
     * @param headers 请求头（可选）
     * @return 响应内容
     */
    public static String postJson(String url, String json, Map<String, String> headers)
            throws IOException, InterruptedException {

        HttpRequest.Builder builder = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .header("Content-Type", "application/json")
                .POST(HttpRequest.BodyPublishers.ofString(json));

        addHeaders(builder, headers);

        return sendRequest(builder.build());
    }

    public static String postJson(String url, String json)
            throws IOException, InterruptedException {
        return postJson(url, json, null);
    }

    private static String sendRequest(HttpRequest request)
            throws IOException, InterruptedException {

        HttpResponse<String> response = DEFAULT_HTTP_CLIENT.send(
                request,
                HttpResponse.BodyHandlers.ofString()
        );

        if (response.statusCode() >= 400) {
            throw new IOException("HTTP Error: " + response.statusCode() + " - " + response.body());
        }

        return response.body();
    }

    private static void addHeaders(HttpRequest.Builder builder, Map<String, String> headers) {
        if (headers != null) {
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                builder.header(entry.getKey(), entry.getValue());
            }
        }
    }

    private static String encodeFormData(Map<String, String> data) {
        if (data == null || data.isEmpty()) {
            return "";
        }

        StringBuilder result = new StringBuilder();
        for (Map.Entry<String, String> entry : data.entrySet()) {
            if (result.length() > 0) {
                result.append("&");
            }
            result.append(URLEncoder.encode(entry.getKey(), StandardCharsets.UTF_8));
            result.append("=");
            result.append(URLEncoder.encode(entry.getValue(), StandardCharsets.UTF_8));
        }
        return result.toString();
    }
}
